package co.edu.uniandes.services;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import co.edu.uniandes.dto.Usuario;
import co.edu.uniandes.dto.Viajero;
import co.edu.uniandes.services.constantes.ConstantesEstadoViajero;
import co.edu.uniandes.services.constantes.ConsultaConstantes;

/**
 * Se encarga de manejar la persistencia de 
 * viajero 
 * @author Diego Alejandro Olivera Rios <diegoalejo14@gmail.com>
 *
 */
public class ServicioViajero implements IServicioViajero {

	/**
	 * Se encarga de guardar un viajero en persistencia
	 * @param viajero viajero que va a ser almacenado
	 * @throws Se lanza cuando se presenta problemas en base de datos
	 */
	@Override
	public void insertar(Viajero viajero) throws Exception, RemoteException {
		Connection con=ConexionBD.getInstance().getConection();
		PreparedStatement ps=null;
		try{
			ps=con.prepareStatement(ConsultaConstantes.INSERT_VIAJERO);
			ps.setString(1, viajero.getNombre());
			ps.setString(2, viajero.getMail());
			ps.setTimestamp(3, new Timestamp(new Date().getTime()));
			ps.setString(4, viajero.getEstado());
			ps.setString(5, viajero.getNotasInactivo());
			ps.setInt(6, viajero.getIdUsuario());
			ps.execute();
		}catch (Exception e) {
			throw e;
		}finally{
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
	}

	/**
	 *Obtiene todos los viajeros que se encuentran en persistencia
	 *@throws Se lanza cuando hay problemas con la base de datos
	 *o con la conexion RMI
	 *@return Lista de viajeros que se encuetran en base de datos
	 * 
	 */
	@Override
	public List<Viajero> consultar() throws Exception, RemoteException {
		Connection con=ConexionBD.getInstance().getConection();
		PreparedStatement ps=null;
		ResultSet rs=null;
		List<Viajero> resultado=new ArrayList<Viajero>();
		try{
			ps=con.prepareStatement(ConsultaConstantes.CONSULTA_VIAJERO);
			rs=ps.executeQuery();
			Viajero viajero;
			while(rs.next()){
				viajero=new Viajero();
				viajero.setId(rs.getInt("id"));
				viajero.setNombre(rs.getString("nombre"));
				viajero.setMail(rs.getString("mail"));
				viajero.setUltimoIngreso(rs.getTimestamp("ultimoIngreso"));
				viajero.setEstado(rs.getString("estado"));
				viajero.setNotasInactivo(rs.getString("notasInactivo"));
				viajero.setIdUsuario(rs.getInt("idUsuario"));
				resultado.add(viajero);
			}
		}catch (Exception e) {
			throw e;
		}finally{
			if(rs!=null && !rs.isClosed()){
				rs.close();
			}
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
		return resultado;
	}


	@Override
	public void eliminar(Integer id) throws Exception, RemoteException {

	}

	/**
	 * Se encarga de modificar el estado de un viajero
	 * ya que por reglas del negocio no se debe eliminar
	 */
	public void cambiarEstado(Viajero viajero,String estado) throws Exception , RemoteException{
		Connection con=ConexionBD.getInstance().getConection();
		PreparedStatement ps=null;
		try{
			ps=con.prepareStatement(ConsultaConstantes.UPDATE_VIAJERO_ESTADO);
			ps.setString(1, estado);
			ps.setInt(2, viajero.getId());
			ps.execute();
		}catch (Exception e) {
			throw e;
		}finally{
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
	}

	/**
	 * Obtiene el viajero de acuerdo al id del usuario ingresado
	 * @param idUsuario Identificador del usuario
	 * @return Si encuentra al usuario retornara los datos del viajero,
	 * de lo contrario retornara null
	 * @throws  Si se presenta problemas con la base de datos
	 */
	@Override
	public Viajero consultarSegunUsuario(int idUsuario) throws Exception, RemoteException {
		Connection con=ConexionBD.getInstance().getConection();
		PreparedStatement ps=null;
		ResultSet rs=null;
		Viajero viajero=null;
		try{
			if(idUsuario==0){
				throw new Exception("El id del usuario no puede ser 0");
			}
			ps=con.prepareStatement(ConsultaConstantes.CONSULTA_VIAJERO_USUARIO);
			ps.setInt(1, idUsuario);
			rs=ps.executeQuery();
			while(rs.next()){
				viajero=new Viajero();
				viajero.setId(rs.getInt("id"));
				viajero.setNombre(rs.getString("nombre"));
				viajero.setMail(rs.getString("mail"));
				viajero.setUltimoIngreso(rs.getTimestamp("ultimoIngreso"));
				viajero.setEstado(rs.getString("estado"));
				viajero.setNotasInactivo(rs.getString("notasInactivo"));
				viajero.setIdUsuario(rs.getInt("idUsuario"));
			}
		}catch (Exception e) {
			throw e;
		}finally{
			if(rs!=null && !rs.isClosed()){
				rs.close();
			}
			if(ps!=null && !ps.isClosed()){
				ps.close();
			}
		}
		return viajero;
	}

	@Override
	public void crearViajero(Usuario user,Viajero viajero) throws Exception {
		IServicioUsuario iServicioUsuario = new ServicioUsuario();
		Usuario autentica=iServicioUsuario.autenticar(user);
		if(autentica!=null) throw new IllegalArgumentException("Ya existe un Usuario registrado en el sistema. Verifique los datos de ingreso");
		iServicioUsuario.insertar(user);
		autentica=iServicioUsuario.autenticar(user);
		viajero.setIdUsuario(autentica.getId());
		viajero.setEstado(ConstantesEstadoViajero.ACTIVO);
		insertar(viajero);
	}

}
